import delegates from '../../utils/delegates'
import initMSE from '../initMSE'
import {formatPlaylist} from '../../utils/option'

class Playlist {
  constructor (player) {
    this.player = player

    delegates(this.player, this)
      .method('getPlaylist')
      .method('getPlaylistItem')
      .method('getPlaylistIndex')
      .method('load')
      .method('reload')
      .method('next')
      .method('prev')
      .method('replay')

    this._subEvent()
  }

  _subEvent () {
    const player = this.player

    player.on('media_ended', () => {
      player.trigger('complete')
      const isPlaylistComplete =
        this.getPlaylistIndex() === this.getPlaylist().length - 1
      if (isPlaylistComplete) {
        if (player._config.repeat) {
          this.reload()
        } else {
          player.trigger('playlistComplete')
        }
      } else {
        this.next()
      }
    })
  }

  load (playlist) {
    const pl = formatPlaylist(playlist)
    if (pl) {
      this.player._config.playlist = pl
      this.player.trigger('playlist', {
        type: 'playlist',
        playlist: pl
      })
      this.reload()
    }
    return !!pl
  }

  reload (play = true) {
    this.setActive(0, 0)
    initMSE.call(this.player)
    play && this.player.play()
  }

  replay () {
    initMSE.call(this.player)
    this.player.play()
  }

  next () {
    const idx = this.getPlaylistIndex()
    const hasNext = this.setActive(idx + 1, 0)
    if (hasNext) {
      this.player.trigger('playlistItem', {
        type: 'playlistItem',
        index: idx + 1,
        item: this.getPlaylistItem(idx + 1)
      })
      initMSE.call(this.player)
      this.player.play()
    }
    return hasNext
  }

  prev () {
    const idx = this.getPlaylistIndex()
    const hasPrev = this.setActive(idx - 1, 0)
    if (hasPrev) {
      this.player.trigger('playlistItem', {
        type: 'playlistItem',
        index: idx - 1,
        item: this.getPlaylistItem(idx - 1)
      })
      initMSE.call(this.player)
      this.player.play()
    }
    return hasPrev
  }

  getPlaylist () {
    return this.player._config.playlist
  }

  getPlaylistItem (index = 0) {
    return this.player._config.playlist[index]
  }

  getPlaylistIndex () {
    for (let i = 0; i < this.player._config.playlist.length; i++) {
      const item = this.player._config.playlist[i]
      if (item.active) {
        return i
      }
    }
    return -1
  }

  setActive (listIndex, sourceIndex = 0) {
    const {playlist} = this.player._config
    const success = !!playlist[listIndex]
    if (!success) {
      return success
    }
    for (let i = 0; i < playlist.length; i++) {
      playlist[i].active = i === listIndex
      for (let j = 0; j < playlist[i].sources.length; j++) {
        playlist[i]['sources'][j].active = j === sourceIndex
      }
    }
    return success
  }
}

export default Playlist
